package com.lzb.compressmaster.utils;

import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import com.arthenica.ffmpegkit.FFmpegKit;
import com.arthenica.ffmpegkit.FFmpegSession;
import com.arthenica.ffmpegkit.ReturnCode;
import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.PathUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 图片格式转换工具类 - 基于FFmpeg实现
 * 支持JPG、PNG、WEBP、BMP等格式互转
 */
public class ImageFormatConverter {

    private static final String TAG = "ImageFormatConverter";

    /**
     * 支持的图片格式
     */
    public static final List<String> SUPPORTED_FORMATS = Arrays.asList(
            "jpg", "jpeg", "png", "webp", "bmp", "tiff", "gif"
    );

    /**
     * 转换监听回调接口
     */
    public interface OnConversionListener {
        void onConversionStart(String inputPath, String outputFormat);

        void onConversionSuccess(String outputPath);

        void onConversionError(String errorMessage);

        void onConversionProgress(int progress);
    }

    /**
     * 转换配置类
     */
    public static class ConversionConfig {
        public int quality = 100;           // 输出质量 (1-100)
        public boolean maintainAspectRatio = true;  // 保持宽高比
        public int maxWidth = 0;          // 最大宽度 (0表示不限制)
        public int maxHeight = 0;         // 最大高度 (0表示不限制)
        public String customOutputPath = null;  // 自定义输出路径
        public boolean overwrite = true;    // 是否覆盖已存在文件

        public ConversionConfig() {
        }

        public ConversionConfig(int quality) {
            this.quality = Math.max(1, Math.min(100, quality));
        }
    }

    /**
     * 转换结果类
     */
    public static class ConversionResult {
        public boolean success;
        public String outputPath;
        public String errorMessage;
        public long fileSize;

        public ConversionResult(boolean success, String outputPath, long fileSize) {
            this.success = success;
            this.outputPath = outputPath;
            this.fileSize = fileSize;
            this.errorMessage = "";
        }

        public ConversionResult(String errorMessage) {
            this.success = false;
            this.errorMessage = errorMessage;
        }
    }

    /**
     * 转换图片格式（异步，带回调）
     *
     * @param context      上下文
     * @param inputPath    输入图片路径
     * @param outputFormat 输出格式 (jpg/png/webp等)
     * @param listener     转换监听回调
     */
    public static void convertImageAsync(Context context, String inputPath, String outputFormat, OnConversionListener listener) {
        convertImageAsync(context, inputPath, outputFormat, new ConversionConfig(), listener);
    }

    /**
     * 转换图片格式（异步，带配置和回调）
     *
     * @param context      上下文
     * @param inputPath    输入图片路径
     * @param outputFormat 输出格式 (jpg/png/webp等)
     * @param config       转换配置
     * @param listener     转换监听回调
     */
    public static void convertImageAsync(Context context, String inputPath, String outputFormat,
                                         ConversionConfig config, OnConversionListener listener) {

        if (listener == null) {
            throw new IllegalArgumentException("OnConversionListener cannot be null");
        }

        // 参数验证
        if (inputPath == null || inputPath.trim().isEmpty()) {
            listener.onConversionError("输入路径不能为空");
            return;
        }

        if (outputFormat == null || outputFormat.trim().isEmpty()) {
            listener.onConversionError("输出格式不能为空");
            return;
        }

        outputFormat = outputFormat.toLowerCase().trim();
        if (!SUPPORTED_FORMATS.contains(outputFormat)) {
            listener.onConversionError("不支持的输出格式: " + outputFormat + "。支持格式: " + SUPPORTED_FORMATS);
            return;
        }

        File inputFile = new File(inputPath);
        if (!inputFile.exists() || !inputFile.canRead()) {
            listener.onConversionError("输入文件不存在或无法读取: " + inputPath);
            return;
        }

        // 启动异步转换任务
        new ImageConversionTask(context, inputPath, outputFormat, config, listener).execute();
    }

    /**
     * 转换图片格式（同步）
     *
     * @param context      上下文
     * @param inputPath    输入图片路径
     * @param outputFormat 输出格式
     * @return ConversionResult 转换结果
     */
    public static ConversionResult convertImageSync(Context context, String inputPath, String outputFormat) {
        return convertImageSync(context, inputPath, outputFormat, new ConversionConfig());
    }

    /**
     * 转换图片格式（同步，带配置）
     *
     * @param context      上下文
     * @param inputPath    输入图片路径
     * @param outputFormat 输出格式
     * @param config       转换配置
     * @return ConversionResult 转换结果
     */
    public static ConversionResult convertImageSync(Context context, String inputPath, String outputFormat, ConversionConfig config) {
        try {
            // 参数验证
            if (inputPath == null || inputPath.trim().isEmpty()) {
                return new ConversionResult("输入路径不能为空");
            }

            if (outputFormat == null || outputFormat.trim().isEmpty()) {
                return new ConversionResult("输出格式不能为空");
            }

            outputFormat = outputFormat.toLowerCase().trim();
            if (!SUPPORTED_FORMATS.contains(outputFormat)) {
                return new ConversionResult("不支持的输出格式: " + outputFormat);
            }

            File inputFile = new File(inputPath);
            if (!inputFile.exists() || !inputFile.canRead()) {
                return new ConversionResult("输入文件不存在或无法读取: " + inputPath);
            }

            // 生成输出路径
            String outputPath = generateOutputPath(inputPath, outputFormat, config);

            // 检查文件是否已存在
            File outputFile = new File(outputPath);
            if (outputFile.exists() && !config.overwrite) {
                return new ConversionResult("输出文件已存在: " + outputPath);
            }

            // 确保输出目录存在
            File parentDir = outputFile.getParentFile();
            if (parentDir != null && !parentDir.exists()) {
                parentDir.mkdirs();
            }

            // 构建FFmpeg命令
            String command = buildFFmpegCommand(inputPath, outputPath, config);

            // 使用FFmpegKit执行转换
            FFmpegSession session = FFmpegKit.execute(command);

            if (ReturnCode.isSuccess(session.getReturnCode()) && outputFile.exists()) {
                long fileSize = outputFile.length();
                return new ConversionResult(true, outputPath, fileSize);
            } else {
                String error = session.getFailStackTrace();
                if (error == null || error.trim().isEmpty()) {
                    error = "FFmpeg转换失败，退出码: " + session.getReturnCode();
                }
                return new ConversionResult(error);
            }

        } catch (Exception e) {
            Log.e(TAG, "转换失败", e);
            return new ConversionResult("转换失败: " + e.getMessage());
        }
    }

    /**
     * 生成输出文件路径
     */
    private static String generateOutputPath(String inputPath, String outputFormat, ConversionConfig config) {
        if (config.customOutputPath != null && !config.customOutputPath.trim().isEmpty()) {
            return config.customOutputPath;
        }

        File inputFile = new File(inputPath);
        String fileName = FileUtils.getFileName(inputPath);
        String baseName = fileName;

        // 移除原扩展名
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex > 0) {
            baseName = fileName.substring(0, lastDotIndex);
        }

        String outputDir = PathUtils.getFilesPathExternalFirst() + "/work/img";

        // 生成唯一文件名
        String outputFileName = baseName + "_converted_" + System.currentTimeMillis() + "." + outputFormat;

        return new File(outputDir, outputFileName).getAbsolutePath();
    }

    /**
     * 构建FFmpeg命令
     */
    private static String buildFFmpegCommand(String inputPath, String outputPath, ConversionConfig config) {
        StringBuilder command = new StringBuilder();

        // 输入文件
        command.append("-i \"").append(inputPath).append("\"");

        // 质量设置
        String outputExtension = getFileExtension(outputPath);
        if ("jpg".equalsIgnoreCase(outputExtension) ||
                "jpeg".equalsIgnoreCase(outputExtension)) {
            int quality = Math.max(2, Math.min(31, (100 - config.quality) * 31 / 100 + 2));
            command.append(" -q:v ").append(quality);
        } else if ("png".equalsIgnoreCase(outputExtension)) {
            int compression = Math.max(0, Math.min(9, (100 - config.quality) / 11));
            command.append(" -compression_level ").append(compression);
        } else if ("webp".equalsIgnoreCase(outputExtension)) {
            command.append(" -quality ").append(config.quality);
        }

        // 尺寸限制
        if (config.maxWidth > 0 && config.maxHeight > 0) {
            if (config.maintainAspectRatio) {
                command.append(" -vf scale=").append(config.maxWidth)
                        .append(":").append(config.maxHeight)
                        .append(":force_original_aspect_ratio=decrease");
            } else {
                command.append(" -vf scale=").append(config.maxWidth)
                        .append(":").append(config.maxHeight);
            }
        } else if (config.maxWidth > 0) {
            command.append(" -vf scale=").append(config.maxWidth).append(":-1");
        } else if (config.maxHeight > 0) {
            command.append(" -vf scale=-1:").append(config.maxHeight);
        }

        // 其他参数
        command.append(" -y");  // 覆盖输出文件

        // 输出文件
        command.append(" \"").append(outputPath).append("\"");

        return command.toString();
    }

    /**
     * 获取文件扩展名
     */
    private static String getFileExtension(String filePath) {
        if (filePath == null || filePath.trim().isEmpty()) {
            return "";
        }

        int lastDotIndex = filePath.lastIndexOf('.');
        if (lastDotIndex > 0 && lastDotIndex < filePath.length() - 1) {
            return filePath.substring(lastDotIndex + 1).toLowerCase();
        }
        return "";
    }

    /**
     * 检查格式是否支持
     */
    public static boolean isFormatSupported(String format) {
        if (format == null || format.trim().isEmpty()) {
            return false;
        }
        return SUPPORTED_FORMATS.contains(format.toLowerCase().trim());
    }

    /**
     * 获取支持的格式列表
     */
    public static List<String> getSupportedFormats() {
        return SUPPORTED_FORMATS;
    }

    /**
     * 异步转换任务
     */
    private static class ImageConversionTask extends AsyncTask<Void, Integer, ImageFormatConverter.ConversionResult> {

        private Context context;
        private String inputPath;
        private String outputFormat;
        private ConversionConfig config;
        private OnConversionListener listener;

        public ImageConversionTask(Context context, String inputPath, String outputFormat,
                                   ConversionConfig config, OnConversionListener listener) {
            this.context = context;
            this.inputPath = inputPath;
            this.outputFormat = outputFormat;
            this.config = config;
            this.listener = listener;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            if (listener != null) {
                listener.onConversionStart(inputPath, outputFormat);
                listener.onConversionProgress(0);
            }
        }

        @Override
        protected ImageFormatConverter.ConversionResult doInBackground(Void... voids) {
            // 模拟进度
            publishProgress(20);

            // 执行同步转换
            ImageFormatConverter.ConversionResult result =
                    ImageFormatConverter.convertImageSync(context, inputPath, outputFormat, config);

            publishProgress(100);
            return result;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            if (listener != null) {
                listener.onConversionProgress(values[0]);
            }
        }

        @Override
        protected void onPostExecute(ImageFormatConverter.ConversionResult result) {
            super.onPostExecute(result);
            if (listener != null) {
                if (result.success) {
                    listener.onConversionSuccess(result.outputPath);
                } else {
                    listener.onConversionError(result.errorMessage);
                }
            }
        }
    }
}